#include <stdio.h>
#include <string.h>

#define MAXLINES 5000
#define MAXLEN 1000
#define MAXMEM 10000
#define ALLOCSIZE 10000

static char allocbuf[ALLOCSIZE];
static char *allocp = allocbuf;

char *alloc(int n)
{
    if(allocbuf + ALLOCSIZE - allocp >= n)
    {
        allocp += n;
        return allocp - n; 
    }
    else
    {
        return 0;
    }    
}

void afree(char *p)
{
    if(p >= allocbuf && p < allocbuf + ALLOCSIZE)
        allocp = p;
}

int getline2(char line[], int maxline)
{
    int c, i;

    for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; i++)
    {
        line[i] = c;
    }
    if (c == '\n')
    {
        line[i] = c;
        i++;
    }
    line[i] = '\0';
    return i;
}

int readlines(char *lineptr[], int maxlines)
{
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;

    while ((len = getline2(line, MAXLEN)) > 0)
    {
        if(nlines >= MAXLINES || (p = alloc(len)) == NULL)
            return -1;
        else
        {
            line[len - 1] = '\0';
            strcpy(p, line);
            lineptr[nlines++] = p;
        }        
    }
    return nlines;
}

int readlines2(char *lineptr[], char *p, int maxlines)
{
    int len, sumlen, nlines;
    char line[MAXLEN];
    nlines = 0;
    sumlen = 0;
    while ((len = getline2(line, MAXLEN)) > 0)
    {
        sumlen += len;
        if(nlines >= MAXLINES || sumlen > MAXMEM)
            return -1;
        else
        {
            line[len - 1] = '\0';
            strcpy(p, line);
            lineptr[nlines++] = p;
            p += len;
        }        
    }
    return nlines;
}

void writelines(char *lineptr[], int nlines)
{
    int i;
    for(i = 0; i < nlines; i++)
        printf("%s\n", lineptr[i]);    
}

char *lineptr[MAXLINES];

int main()
{
    char mem[MAXMEM];
    int nlines;
    nlines = readlines(lineptr, MAXLINES);
    printf("nlines = %d\n", nlines);
    writelines(lineptr, nlines);   

    nlines = readlines2(lineptr, mem, MAXLINES);
    printf("nlines = %d\n", nlines);
    writelines(lineptr, nlines);  

    return 0;
}